package com.fingard.dsp.bank.reqrespobj;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.HashSet;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextWriter;

public class RetAtsBase {
	
	public final String PATH_Detail = "/ATSYH/TransResp/TransParam/DetailRecord";
	
	public ReqRespHeader retHeader;
	public XmlTextWriter retXmlWriter;
	
	
	public void writeStart(){
		retXmlWriter.writeStartDocument();
		retXmlWriter.writeStartElement("ATSYH");
		retXmlWriter.writeStartElement("TransResp");

		String bankCode = retHeader.bankCode;
		if (retHeader.bankCode.startsWith("CSRS")) {
            bankCode = retHeader.srcBankCode;
        }
        if ("Contract".equalsIgnoreCase(retHeader.transType) || "QryContract".equalsIgnoreCase(retHeader.transType)
                || "QryBatContract".equalsIgnoreCase(retHeader.transType) || "UpContract".equalsIgnoreCase(retHeader.transType)
                || "DeContract".equalsIgnoreCase(retHeader.transType) || "QryDeContract".equalsIgnoreCase(retHeader.transType)) {
            if (retHeader.srcBankCode != null && retHeader.srcBankCode.startsWith("FnGrd") && retHeader.srcBankCode.length() == 8) {
                bankCode = retHeader.srcBankCode;
            }
        }
		retXmlWriter.writeElementString("BankCode", bankCode);
		/*if ("ROA".equals(retHeader.transType)) {
			retHeader.transType = "QryStatement";
		}*/
		retXmlWriter.writeElementString("TransType", retHeader.transType);
		retXmlWriter.writeElementString("TransSeqID", retHeader.transSeqID);
		
		retXmlWriter.writeStartElement("TransParam");
	}
	
	public boolean hasWrittenRespCode = false;
	public boolean hasWrittenRespInfo = false;
	
	public void writeRespCode(String respCode) throws Exception {
//		if(hasWrittenRespCode){
//			throw new Exception("重复写入RespCode");
//		}
//		retXmlWriter.writeElementString("RespCode", respCode);
//		hasWrittenRespCode = true;
        if (!hasWrittenRespCode) {
            retXmlWriter.writeElementString("RespCode", respCode);
            hasWrittenRespCode = true;
        }
    }
	public void writeRespInfo(String respInfo) throws Exception{
//		if(hasWrittenRespInfo){
//			throw new Exception("重复写入RespInfo");
//		}
//		retXmlWriter.writeElementString("RespInfo", respInfo);
//		hasWrittenRespInfo = true;
		if (!hasWrittenRespInfo) {
			retXmlWriter.writeElementString("RespInfo", respInfo);
            hasWrittenRespInfo = true;
		}
	}
	
	public void writeBatRespCode(String respCode) throws Exception{
		if(hasWrittenRespCode){
			throw new Exception("重复写入BatRespCode");
		}
		retXmlWriter.writeElementString("BatRespCode", respCode);
		hasWrittenRespCode = true;
	}
	public void writeBatRespInfo(String respInfo) throws Exception{
		if(hasWrittenRespInfo){
			throw new Exception("重复写入BatRespInfo");
		}
		retXmlWriter.writeElementString("BatRespInfo", respInfo);
		hasWrittenRespInfo = true;
	}
	
	public void writeException(Exception ex){
		if(retHeader!=null){
			FGBiz.limitMsg.exception(retHeader.bankCode+"."+retHeader.transType, ex);
		}else{
			FGBiz.limitMsg.exception("RetAtsBase.Other", ex);
		}
		retXmlWriter.writeElementString("Exception", LogHelper.getStackTrace(ex));
	}
	
	public void writeXElement(XElement xe){
		retXmlWriter.writeXElement(xe);
	}
	
	public void writeEnd(){
		retXmlWriter.writeEndDocument();
	}
	
	public String getRetAtsString(){
		return retXmlWriter.toXmlString();
	}
	
	/**将对象写入<DetailRecord>，首字母大写
	 * @param pAdvNmMap 不符合首字母大写规则的，另行在这个map里指定节点名称映射（key大小写敏感）
	 * @param pIgnoreFields 需要过滤的对象属性，是java代码中的，不写的（key大小写敏感）
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException */
	public void writeToXmlDetailRecord(Object pObj, HashMap<String, String> pAdvNmMap, HashSet<String> pIgnoreFields) throws IllegalArgumentException, IllegalAccessException{
		Field[] fields = pObj.getClass().getFields();
		retXmlWriter.writeStartElement("DetailRecord");
		for(int i=0;i<fields.length;i++){
			String eachType = fields[i].getGenericType().toString().toLowerCase();
			String aName = fields[i].getName();
			if(pIgnoreFields !=null && pIgnoreFields.contains(aName)){
				continue;
			}
			String nodeName;
			if(pAdvNmMap!=null && pAdvNmMap.containsKey(aName)){
				nodeName = pAdvNmMap.get(aName);
			}else{
				String chr0 = aName.charAt(0)+"";
				nodeName = chr0.toUpperCase() + aName.substring(1);
			}
			Object val = fields[i].get(pObj);
			String strVal = "";
			if(eachType.contains("date")){
				if(val != null && val.toString().length() > 0){
					strVal = new SimpleDateFormat(Format.DateTimeFormatStr19).format(val);
				}
			}else if(val != null){
				strVal = val.toString();
			}
			retXmlWriter.writeElementString(nodeName, strVal);
		}
		retXmlWriter.writeEndElement();
	}
}
